﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CapaDatos;
using System.Collections;

namespace CapaNegocio
{
    public class OrdenTrabajo:IBaseDeDatos 
    {
        #region atributos
        private int codigo;
        private DateTime fechaComienzo;
        private EstadoOT estadoOT;
        private Cliente cliente;
        private Presupuesto presupuesto;


        public EstadoOT EstadoOT
        {
            get { return estadoOT; }
            set { estadoOT = value; }
        }

        public int Codigo
        {
            get { return codigo; }
            set { codigo = value; }
        }
       

        public DateTime FechaComienzo
        {
            get { return fechaComienzo; }
            set { fechaComienzo = value; }
        }
       
        public Cliente Cliente
        {
            get { return cliente; }
            set { cliente = value; }
        }


        public Presupuesto Presupuesto
        {
            get { return presupuesto; }
            set { presupuesto = value; }
        }
        public string TextoAmostrar
        {
            get { return textoAMostrar(); }
     
        }
        #endregion

        #region metodos estaticos

        public void modificarOT(int pIdEstado)
        {
            try
            {

                ServidorDatos.modificarOT(this.codigo,pIdEstado);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        public static long crearOT(Cliente cli, Presupuesto presup, DateTime fechaInicio, DateTime fechaFin)
        {
           return ServidorDatos.registrarOT(cli.Id,presup.Id,fechaInicio, fechaFin);
        }

        public static List<OrdenTrabajo> buscarOrdenes()
        {
            ArrayList otBD = ServidorDatos.buscarOrdenesDeTrabajo();
            List<OrdenTrabajo> orden = new List<OrdenTrabajo>();
            for (int i = 0; i < otBD.Count; i++)
            {
                OrdenTrabajo o= new OrdenTrabajo();
                o.buildObject((ArrayList)otBD[i]);
                orden.Add(o);
            }
            return orden;
        }

        public static List<OrdenTrabajo> buscarOrdenesNoAsignadas()
        {
            ArrayList otBD = ServidorDatos.buscarOrdenesNoAsignadas();
            List<OrdenTrabajo> orden = new List<OrdenTrabajo>();
            for (int i = 0; i < otBD.Count; i++)
            {
                OrdenTrabajo o = new OrdenTrabajo();
                o.buildObject((ArrayList)otBD[i]);
                orden.Add(o);
            }
            return orden;
        }


        public static OrdenTrabajo buscarOrden(int codigo)
        {
            ArrayList orden = ServidorDatos.buscarOrdenDeTrabajo(codigo);
            if (orden.Count == 1)
            {
                OrdenTrabajo o = new OrdenTrabajo();
                o.buildObject((ArrayList)orden[0]);
                return o;
            }
            else
            {
                return null;
            }  

        }

        public String fechaFin()
        {
            List<EtapaObra> list = EtapaObra.buscarEtapas(this.codigo);
            EtapaObra etapa = list.Find(delegate(EtapaObra eo)
            {
                return eo.Etapa.Codigo == (int)EtapaEnum.CONTRAPISO_PERIMETRAL;
            });

            if (etapa !=null && etapa.FechaFin != default(DateTime))
            {
                return etapa.FechaFin.ToShortDateString();
            }
            else {
                return "No determinada";
            }
        }

        public EtapaObra buscarEtapaActual()
        {
            List<EtapaObra> list = EtapaObra.buscarEtapas(this.codigo);
            EtapaObra etapa = list.FindLast(delegate(EtapaObra eo)
            {
                return eo.FechaFin != default(DateTime);
            });
            
            if(etapa==null){
                etapa = new EtapaObra("Aún no tiene etapas cargadas");
            }
          
           return etapa;
            
           
        }

        public EtapaObra buscarEtapaActualReal()
        {
            List<EtapaObra> list = EtapaObra.buscarEtapas(this.codigo);
            EtapaObra etapa = list.FindLast(delegate(EtapaObra eo)
            {
                return (eo.FechaInicioReal != default(DateTime) && eo.FechaFinReal != default(DateTime)) || eo.FechaInicioReal != default(DateTime);
            });

            if (etapa == null)
            {
                etapa = new EtapaObra("La obra aun no ha comenzado");
            }

            return etapa;


        }


        public int totalDiasUtilizados() { 
        
            List<EtapaObra> list = EtapaObra.buscarEtapas(this.codigo);
       
            int i =0;
            
            foreach (EtapaObra e in list) {

                i = i + e.DiasTotalesReales();
            }

            return i;
        
        }

        public int totalDiasAFavor()
        {

           return diasTotalesEstipulados() - totalDiasUtilizados();

        }

        public int diasTotalesEstipulados()
        {
            char[] separador = { '/' };
            string[] split = fechaFin().Split(separador);
            DateTime dt = new DateTime();
            if (split.Length == 3)
            {
                dt = new DateTime(Convert.ToInt32(split[2]), Convert.ToInt32(split[1]), Convert.ToInt32(split[0]));
            }
            return dt.Subtract(fechaComienzo).Days < 0 ? 0 : dt.Subtract(fechaComienzo).Days;
        }


        public String textoAMostrar() { 
            return codigo + " - " + fechaComienzo.ToShortDateString()+" - "+estadoOT.Descripcion;
        }
        #endregion

        public void buildObject(ArrayList lista)
        {
            codigo = Convert.ToInt32(lista[0].ToString());
            Presupuesto presupuesto = Presupuesto.buscarPresupuesto(Convert.ToInt32(lista[1].ToString()));
            this.presupuesto = presupuesto;
            EstadoOT estadoOT = EstadoOT.buscarEstado(Convert.ToInt32(lista[2].ToString()));
            this.estadoOT = estadoOT;
            Cliente cliente = Cliente.buscarCliente(Convert.ToInt32(lista[3].ToString()));
            this.cliente = cliente;
            fechaComienzo = Convert.ToDateTime(lista[4].ToString());
        }

        public bool eliminar()
        {
            bool devolver = false;

            if (EtapaObra.buscarEtapas(codigo).Count == 0)
            {
                devolver = ServidorDatos.eliminarAsignacion(this.Codigo) && ServidorDatos.eliminarOrdenTrabajo(codigo);

            }

            return devolver;
        }

        public bool actualizar(long idPresupuesto, long idCliente, DateTime fechaComienzo)
        {

            bool devolver = false;

            if (EtapaObra.buscarEtapas(codigo).Count == 0)
                devolver = ServidorDatos.actualizarOrdenTrabajo(codigo, idPresupuesto, idCliente, fechaComienzo);
            return devolver;
        }

        public static OrdenTrabajo buscarPresupuesto(Presupuesto p) {

            ArrayList orden = ServidorDatos.buscarPresupuestoEnOT(p.Id);
            if (orden.Count == 1)
            {
                OrdenTrabajo o = new OrdenTrabajo();
                o.buildObject((ArrayList)orden[0]);
                return o;
            }
            else
            {
                return null;
            }  
        
        }


        public static List<OrdenTrabajo> buscarOrdenes(int codConstructor)
        {
            ArrayList otBD = ServidorDatos.buscarOrdenesDeTrabajo(codConstructor);
            List<OrdenTrabajo> orden = new List<OrdenTrabajo>();
            for (int i = 0; i < otBD.Count; i++)
            {
                OrdenTrabajo o = new OrdenTrabajo();
                o.buildObject((ArrayList)otBD[i]);
                orden.Add(o);
            }
            return orden;
        }

        public static OrdenTrabajo buscarOrden(int codigo,int codConstructor)
        {
            ArrayList orden = ServidorDatos.buscarOrdenDeTrabajo(codigo, codConstructor);
            if (orden.Count == 1)
            {
                OrdenTrabajo o = new OrdenTrabajo();
                o.buildObject((ArrayList)orden[0]);
                return o;
            }
            else
            {
                return null;
            }

        }


        public bool actualizarFinOT()
        {
            return ServidorDatos.actualizarFinDeOT(this.Codigo);
        }
    }
}
